"""
Logging middleware following SOLID principles.
"""

import time
import uuid
from typing import Callable
from fastapi import Request, Response
from fastapi.responses import JSONResponse
from .logger import get_logger


class LoggingMiddleware:
    """Middleware for logging HTTP requests and responses."""
    
    def __init__(self, app):
        self.app = app
        self.logger = get_logger("middleware")
    
    async def __call__(self, scope, receive, send):
        if scope["type"] != "http":
            await self.app(scope, receive, send)
            return
        
        request = Request(scope, receive)
        
        # Generate request ID
        request_id = str(uuid.uuid4())
        
        # Start timing
        start_time = time.time()
        
        # Create bound logger with request context
        request_logger = self.logger.bind(
            request_id=request_id,
            method=request.method,
            url=str(request.url),
            user_agent=request.headers.get("user-agent"),
            client_ip=request.client.host if request.client else None
        )
        
        # Log request start
        request_logger.info("Request started")
        
        # Process request
        response = None
        status_code = 500
        
        async def send_wrapper(message):
            nonlocal response, status_code
            if message["type"] == "http.response.start":
                status_code = message["status"]
            await send(message)
        
        try:
            await self.app(scope, receive, send_wrapper)
            
        except Exception as e:
            # Log exception
            request_logger.exception("Request failed", error=str(e))
            
            # Return error response
            error_response = JSONResponse(
                status_code=500,
                content={"detail": "Internal server error", "request_id": request_id}
            )
            await error_response(scope, receive, send)
            
        finally:
            # Calculate duration
            duration = time.time() - start_time
            
            # Log request completion
            request_logger.log_request(
                method=request.method,
                url=str(request.url),
                status_code=status_code,
                duration=duration
            )


def create_logging_middleware():
    """Create logging middleware instance."""
    return LoggingMiddleware